﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zanox.Api.Client.Auth.V20110501;

namespace Zanox.Api.Client.Auth.V20110501
{
    public class ConnectAPI
    {
        protected Zanox.Api.Client.Auth.V20110501.ConnectService connectService;

        public ConnectAPI() : this(null) { }
        public ConnectAPI(System.Net.IWebProxy proxy)
        {
            connectService = new Zanox.Api.Client.Auth.V20110501.ConnectService();
            connectService.Proxy = proxy;
            connectService.EnableDecompression = true;
            connectService.UserAgent = Constants.UserAgent;
        }

        #region zanox Connect

        public static string GetAuthURL(string applicationId)
        {
            return string.Format(Constants.AuthURLTemplate, applicationId);
        }

        /// <summary>
        /// Returns the zanox Connect Session of the user of an Application
        /// </summary>
        /// <param name="publicKey">publicKey of the Application</param>
        /// <param name="secretKey">secretKey of the Application</param>
        /// <param name="authToken">Authtoken provided by zanox Connect OAuth Workflow after user successfully loged in</param>
        /// <returns></returns>
        public sessionType GetSession(string publicKey, string secretKey, string authToken)
        {
            getSession parameters = new getSession();
            DateTime timestamp = DateTime.UtcNow;

            parameters.authToken = authToken;
            parameters.nonce = Signature.GetNonce();
            parameters.publicKey = publicKey;
            parameters.signature = Signature.SoapSignature(timestamp, secretKey, "connectservice", "getsession", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timestamp);
            
            getSessionResponse response = connectService.getSession(parameters);

            if (response == null)
            {
                return null;
            }

            sessionType session = response.session;
            return session;
        }

        /// <summary>
        /// Returns the zanox Connect Offline Session based on the users OfflineToken
        /// </summary>
        /// <param name="publicKey">publicKey of the Application</param>
        /// <param name="secretKey">secretKey of the Application</param>
        /// <param name="offlineToken">OfflineToken provided by zanox Connect OAuth Workflow after user successfully loged in and acceptance of offlineSession</param>
        /// <returns></returns>
        public offlineSessionType GetOfflineSession(string publicKey, string secretKey, string offlineToken)
        {
            getOfflineSession parameters = new getOfflineSession();
            DateTime timestamp = DateTime.UtcNow;

            parameters.offlineToken = offlineToken;
            parameters.nonce = Signature.GetNonce();
            parameters.publicKey = publicKey;
            parameters.signature = Signature.SoapSignature(timestamp, secretKey, "connectservice", "getofflinesession", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timestamp);
            
            getOfflineSessionResponse response = connectService.getOfflineSession(parameters);

            if (response == null)
            {
                return null;
            }

            offlineSessionType session = response.session;
            return session;
        }

        /// <summary>
        /// Closes a zanox Connect Session
        /// This request has to signed with publicKey&secretKey of the app.
        /// </summary>
        public void CloseSession(sessionType session, string publicKey, string secretKey)
        {
            closeSession parameters = new closeSession();

            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, secretKey, "connectservice", "closesession", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);
            parameters.publicKey = publicKey;
            connectService.closeSession(parameters);
        }

        /// <summary>
        /// Extends a zanox Connect Session
        /// This request has to signed with publicKey&secretKey of the app.
        /// </summary>       
        public promoteSessionResponse PromoteSession(sessionType session, string publicKey, string secretKey, promoteTypeEnum promoteType)
        {
            promoteSessionRequest parameters = new promoteSessionRequest();

            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, secretKey, "connectservice", "promotesession", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);
            parameters.publicKey = publicKey;

            parameters.promoteType = promoteType;
            
            promoteSessionResponse response = connectService.promoteSession(parameters);
            return response;
        }

        /// <summary>
        /// Assigns an User to an Application and creates a zanox ConnectId
        /// This methode is reserved for some applications
        /// </summary>
        public string CreateConnect(string connectId, string secretKey, string publicKey, string applicationId, roleType role)
        {
            createConnectRequest parameters = new createConnectRequest();

            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.publicKey = publicKey;
            parameters.connectId = connectId;
            parameters.signature = Signature.SoapSignature(now, secretKey, "connectservice", "createconnect", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            // usierlogin behind this connectId is connected
            parameters.connectId = connectId;

            // application to connect to
            parameters.applicationId = applicationId;

            // role of connection: customer or tester
            parameters.role = role;
            parameters.roleSpecified = true;

            //TODO
            /*             
            parameters.loginId = ;
            parameters.loginIdSpecified=true;
            */

            createConnectResponse response = connectService.createConnect(parameters);
            if (response == null)
            {
                return null;
            }

            return response.connectId;
        }

        /// <summary>
        /// Returns the URL to jump into the zanox UI for a given session of the user
        /// </summary>
        public string GetZanoxUIUrl(sessionType session)
        {
            getUiUrl parameters = new getUiUrl();

            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.timestamp = Signature.GetZDateTime(now);
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "connectservice", "getuiurl", parameters.nonce);
            parameters.sessionKey = session.secretKey;

            getUiUrlResponse response = connectService.getUiUrl(parameters);
            if (response == null)
            {
                return null;
            }
            return response.url;
        }
        #endregion


        #region TODO
        /// <summary>
        /// 
        /// </summary>
        public string GetUserLogin()
        {
            throw new NotImplementedException();
        }
        
        /// <summary>
        /// 
        /// </summary>
        public string CreateAnonymousUserLogin()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        public string UpdateAnonymousUserLogin()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        public string DeleteAnonymousUserLogin()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        public string GetPermanentToken()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        public string GetSessionForMarketplace()
        {
            throw new NotImplementedException();
        }        
        #endregion
    }
}
